import * as crypto from 'crypto';

/**
 * 生成随机令牌
 */
export function generateToken(length: number = 32): string {
  return crypto.randomBytes(length).toString('hex');
}

/**
 * 为密码生成盐值
 */
export function generateSalt(length: number = 16): string {
  return crypto.randomBytes(length).toString('hex');
}

/**
 * 使用盐值哈希密码
 */
export function hashPassword(password: string, salt: string): string {
  return crypto
    .createHmac('sha512', salt)
    .update(password)
    .digest('hex');
}

/**
 * 验证密码
 */
export function verifyPassword(password: string, salt: string, hashedPassword: string): boolean {
  const hash = hashPassword(password, salt);
  return hash === hashedPassword;
}

/**
 * 生成JWT令牌
 * 注意：这是一个简化版的实现，实际项目中应该使用jwt库
 */
export function generateJwtToken(payload: any, secret: string, expiresIn: number): string {
  const header = { alg: 'HS256', typ: 'JWT' };
  const currentTime = Math.floor(Date.now() / 1000);
  const exp = currentTime + expiresIn;
  
  const encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64').replace(/=/g, '');
  const encodedPayload = Buffer.from(JSON.stringify({ ...payload, exp })).toString('base64').replace(/=/g, '');
  
  const signature = crypto
    .createHmac('sha256', secret)
    .update(`${encodedHeader}.${encodedPayload}`)
    .digest('base64')
    .replace(/=/g, '');
  
  return `${encodedHeader}.${encodedPayload}.${signature}`;
}

/**
 * 验证JWT令牌
 * 注意：这是一个简化版的实现，实际项目中应该使用jwt库
 */
export function verifyJwtToken(token: string, secret: string): any | null {
  try {
    const [encodedHeader, encodedPayload, signature] = token.split('.');
    
    const expectedSignature = crypto
      .createHmac('sha256', secret)
      .update(`${encodedHeader}.${encodedPayload}`)
      .digest('base64')
      .replace(/=/g, '');
    
    if (signature !== expectedSignature) {
      return null;
    }
    
    const payload = JSON.parse(Buffer.from(encodedPayload, 'base64').toString());
    const currentTime = Math.floor(Date.now() / 1000);
    
    if (payload.exp && payload.exp < currentTime) {
      return null;
    }
    
    return payload;
  } catch (error) {
    return null;
  }
}